import CryptoJS from 'crypto-js';
import { UUID } from 'uuid-generator-ts';
import { system,user } from '@/store';
import { SM4,SM2 } from 'gm-crypto';
import { sm2} from 'sm-crypto';
import * as u from '@/tool/function/util'
import systemConfig from '@/common/config';
/* 常用加解密 */
//MD5加密
export function MD5(data: string | CryptoJS.lib.WordArray) {
  return CryptoJS.MD5(data).toString();
}
//BASE64加解密

export function encryptBASE64(data: string) {
  return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data));
}
export function decryptBASE64(cipher: string) {
  return CryptoJS.enc.Base64.parse(cipher).toString(CryptoJS.enc.Utf8);
}
//AES加解密
export function encryptAES(data: string | CryptoJS.lib.WordArray, secretKey: string) {
  if (!secretKey) {
    secretKey = decryptBASE64(system.defaultAESKey);
  }
  const result = CryptoJS.AES.encrypt(data, CryptoJS.enc.Utf8.parse(secretKey), {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7,
  });
  return result.toString();
}
export function decryptAES(cipher: string | CryptoJS.lib.CipherParams, secretKey: string) {
  if (!secretKey) {
    secretKey = decryptBASE64(system.defaultAESKey);
  }
  const result = CryptoJS.AES.decrypt(cipher, CryptoJS.enc.Utf8.parse(secretKey), {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7,
  });
  return CryptoJS.enc.Utf8.stringify(result);
}
function gotoLogin(){
	u.delCookie(systemConfig.localTokenName);
	u.delCookie(systemConfig.localRefreshTokenName);
		
}
export function decryptSM4(data: string , secretKey: any) {
	let key='';
	if (!secretKey) {
		const token = user.accesstoken;
		if(token){
			if(user.defaultSM4Key){
				secretKey=user.defaultSM4Key
			}else{
				let secretStr=u.getCookie("USERSECRET");
				if(secretStr){
					let secret=JSON.parse(decryptSM4(secretStr,system.defaultSM4Key));
					secretKey=secret.defaultSM4Key
					user.setUserSecret(secret);
				}else{
					gotoLogin()
				}
			}
		}else{
			key = system.defaultSM4Key;
		}
	}else{
		key=secretKey
	}
	const result = SM4.decrypt(data, key, {
		inputEncoding: 'base64',
		outputEncoding: 'utf8'
	});
	return result;
}

export function encryptSM4(data: string , secretKey: any) {
	let key='';
	if (!secretKey) {
		const token = user.accesstoken;
		if(token){
			if(user.defaultSM4Key){
				secretKey=user.defaultSM4Key
			}else{
				let secretStr=u.getCookie("USERSECRET");
				if(secretStr){
					let secret=JSON.parse(decryptSM4(secretStr,system.defaultSM4Key));
					secretKey=secret.defaultSM4Key
					user.setUserSecret(secret);
				}else{
					gotoLogin()
				}
			}
		}else{
			key = system.defaultSM4Key;
		}
	}else{
		key=secretKey
	}
	const result = SM4.encrypt(data, key, {
		inputEncoding: 'utf8',
		outputEncoding: 'base64'
	});
	return result;
}
export function decryptSM2(data: string , secretKey: any) {
	if (!secretKey) {
		const token = user.accesstoken;
		if(token){
			if(user.defaultSM2PrivateKey){
				secretKey=user.defaultSM2PrivateKey
			}else{
				let secretStr=u.getCookie("USERSECRET");
				if(secretStr){
					let secret=JSON.parse(decryptSM4(secretStr,system.defaultSM4Key));
					secretKey=secret.defaultSM2PrivateKey
					user.setUserSecret(secret);
				}else{
					gotoLogin()
				}
			}
		}else{
			secretKey = system.defaultSM2PrivateKey;
		}
	}
	try{
        //判断返回的密文是否是数组
        let result='';
        if (data.startsWith("[")) {
            const encryptedSegments = JSON.parse(data);
            for (const encryptedSegment of encryptedSegments) {
                let segment=encryptedSegment;
                if (encryptedSegment.substr(0, 2) == '04') {
                    segment = encryptedSegment.substr(2);
                }
                /* const decryptedSegment = SM2.decrypt(segment, secretKey, {
                    inputEncoding: 'hex',
                    outputEncoding: 'utf8'
                });*/
                const decryptedSegment = sm2.doDecrypt(segment, secretKey);
                result += decryptedSegment;
            }
        }else{
            if (data.substring(0, 2) == '04') {
                data = data.substring(2);
            }
            /*const decryptedSegment = SM2.decrypt(data, secretKey, {
                inputEncoding: 'hex',
                outputEncoding: 'utf8'
            });*/
            const decryptedSegment = sm2.doDecrypt(data, secretKey);
            result += decryptedSegment;
        }
		return result;
	}catch(e){
		console.error("解析异常：",e)
		return data;
	}
	
	
}

export function encryptSM2(data: string , secretKey: any) {
	if (!secretKey) {
		const token = user.accesstoken;
		if(token){
			if(user.defaultSM2PublicKey){
				secretKey=user.defaultSM2PublicKey
			}else{
				let secretStr=u.getCookie("USERSECRET");
				if(secretStr){
					let secret=JSON.parse(decryptSM4(secretStr,system.defaultSM4Key));
					secretKey=secret.defaultSM2PublicKey
					user.setUserSecret(secret);
				}else{
					gotoLogin()
				}
			}
			
		}else{
			secretKey = system.defaultSM2PublicKey;
		}
		
	}
	try{
        //判断是否分段加密
        if(!systemConfig.splitFlag){
            /*return '04'+SM2.encrypt(data, secretKey,{
               inputEncoding: 'utf8',
               outputEncoding: 'hex'
           });*/
            return '04'+sm2.doEncrypt(data, secretKey);
        }else{
            const segmentSize=2560*4;
            const encryptedSegments = [];
            for (let i = 0; i < data.length; i += segmentSize) {
                const segment = data.slice(i, i + segmentSize);
                /* const encryptedSegment = SM2.encrypt(segment, secretKey,{
                     inputEncoding: 'utf8',
                     outputEncoding: 'hex'
                 });*/
                const encryptedSegment = sm2.doEncrypt(segment, secretKey);
                encryptedSegments.push("04"+encryptedSegment);
            }
            return JSON.stringify(encryptedSegments);
        }
	}catch(e){
		console.error("加密异常：",e)
		return data;
	}
}

export function isIE() {
  const bw = window.navigator.userAgent;
  const compare = (s: any) => bw.indexOf(s) >= 0;
  const ie11 = (() => 'ActiveXObject' in window)();
  return compare('MSIE') || ie11;
}

/**
 * Remove loading animate
 * @param id parent element id or class
 * @param timeout
 */
export function removeLoadingAnimate(id = '', timeout = 1500) {
  if (id === '') {
    return;
  }
  setTimeout(() => {
    document.body.removeChild(<any>document.getElementById(id));
  }, timeout);
}
/**
 * Remove an item from an array.
 */
export function remove(arr: any[], item: any) {
  if (arr.length) {
    const index = arr.indexOf(item);
    if (index > -1) {
      return arr.splice(index, 1);
    }
  }
}
export function isRegExp(v: any) {
  return _toString.call(v) === '[object RegExp]';
}
export interface BrowerModel {
  browserVersion: string | number;
  browserType: string;
}
/*
 * 获取浏览器版本信息
 */
export function getBrowerInfo(): BrowerModel {
  const userAgent = navigator?.userAgent.toLowerCase() || '';
  let browserType = '';
  let browserVersion = '';
  // #ifdef MP-WEIXIN
  browserType = 'weixin';
  // #endif
  // #ifdef MP-ALIPAY
  browserType = 'alipay';
  // #endif
  // #ifdef H5
  // 浏览器类型-IE
  if (userAgent.match(/msie/) != null || userAgent.match(/trident/) != null) {
    browserType = 'ie';
    browserVersion = getIeVersion();
  } else if (window.opera || userAgent.indexOf('opr') > 0) {
    // 欧朋
    browserType = 'opr';
    browserVersion = getOperaVersion(userAgent);
  } else if (userAgent.indexOf('ubrowser') > 0) {
    browserType = 'uc';
    let ver = userAgent.match(/ubrowser\/([\d.]+)/);
    if (ver) {
      browserVersion = ver[1];
    }
  } else if (userAgent.indexOf('bidubrowser') > 0) {
    // 百度
    browserType = 'baidu';
    let ver = userAgent.match(/bidubrowser\/([\d.]+)/);
    if (ver) {
      browserVersion = ver[1];
    }
  } else if (userAgent.indexOf('metasr') > 0 || userAgent.indexOf('se 2.x') > 0) {
    // 搜狗
    browserType = 'metasr';
    // browserVersion =  userAgent.match(/metasr\/([\d.]+)/)[1]
  } else if (userAgent.indexOf('tencenttraveler') > 0) {
    browserType = 'qq';
    let ver = userAgent.match(/tencenttraveler\/([\d.]+)/);
    if (ver) {
      browserVersion = ver[1];
    }
  } else if (userAgent.indexOf('qqbrowser') > 0) {
    browserType = 'qq';
    let ver = userAgent.match(/qqbrowser\/([\d.]+)/);
    if (ver) {
      browserVersion = ver[1];
    }
  } else if (userAgent.match(/MicroMessenger/i) == 'micromessenger' || userAgent.match(/WeiBo/i) == 'weibo') {
    browserType = 'weixin';
  } else if (userAgent.match(/AlipayClient/i) == 'alipayclient') {
    browserType = 'alipay'; //支付宝
  } else if (userAgent.indexOf('dtdreamweb') > -1) {
    browserType = 'zlb'; //浙里办app
  } else if (userAgent.indexOf('miniprogram') > -1 && userAgent.indexOf('alipay') > -1) {
    browserType = 'zlb-alipay'; //浙里办小程序
  } else if (userAgent.indexOf('DingTalk') > -1) {
    browserType = 'dingding'; //钉钉
  } else if (userAgent.indexOf('maxthon') > 0) {
    // 遨游
    browserType = 'maxthon';
    let ver = userAgent.match(/maxthon\/([\d.]+)/);
    if (ver) {
      browserVersion = ver[1];
    }
  } else if (userAgent.indexOf('firefox') > 0) {
    // 火狐
    browserType = 'firefox';
    let ver = userAgent.match(/firefox\/([\d.]+)/);
    if (ver) {
      browserVersion = ver[1];
    }
  } else if (userAgent.indexOf('edge') > 0) {
    // edge
    browserType = 'edge';
    let ver = userAgent.match(/edge\/([\d.]+)/);
    if (ver) {
      browserVersion = ver[1];
    }
  } else if (userAgent.indexOf('chrome') > 0) {
    // 谷歌/360
    if (validate360('type', 'application/x360mmplugin')) {
      browserType = '360';
      // browserVersion =  userAgent.match(/chrome\/([\d.]+)/)[1]
    } else {
      browserType = 'chrome';
      let ver = userAgent.match(/chrome\/([\d.]+)/);
      if (ver) {
        browserVersion = ver[1];
      }
    }
  } else if (userAgent.indexOf('Safari') > -1) {
    // 苹果
    browserType = 'safari';
    let ver = userAgent.match(/version\/([\d.]+)/);
    if (ver) {
      browserVersion = ver[1];
    }
  } else {
    browserType = 'other';
  }
  // #endif
  const browser = { browserType: browserType, browserVersion: browserVersion };
  return browser;
}
/*
 * 判断是否为360浏览器
 */
export function validate360(option: string, value: string) {
  const mimeTypes: any = window.navigator.mimeTypes;
  for (const mt in mimeTypes) {
    if (mimeTypes[mt][option] === value) {
      return true;
    }
  }
  return false;
}
/*
 * 获取IE浏览器版本
 */
export function getIeVersion() {
  const IEMode = document.DOCUMENT_NODE;
  const rMsie = /(msie\s|trident.*rv:)([\w.]+)/;
  const ma = window.navigator.userAgent.toLowerCase();
  const match: any = rMsie.exec(ma);
  try {
    return match[2] + '';
  } catch (e) {
    return IEMode + '';
  }
}
/*
 * 获取oper浏览器版本
 */
export function getOperaVersion(userAgent: any) {
	try {
		let s = userAgent.match(/opera\/([\d.]+)/)[1];
		let version = s[1].split('.');
		return version[0];
	} catch (e) {
		return 0;
	}
}
export function getZlbUiStyle(){
	if(ZWJSBridge){
		ZWJSBridge.getUiStyle().then((result:any) => {
			console.log("获取到的浙里办api返回值：")
			console.log(result);
			system.setUiStyle(result.uiStyle)
		}).catch((error:any) => {
			console.log("浙里办环境风格获取失败！使用标准模式")
			system.setUiStyle('normal')
		});
	}
	
}
//是否老年版
export function isElder() {
  let flag = false;
  let ui_style = system.uiStyle;
  if (ui_style) {
    if (ui_style === 'elder') {
      flag = true;
    }
  }
  return flag;
}
export function uuid() {
  const uuid = new UUID();
  return uuid.getDashFreeUUID();
}
export function formtojson(params: any) {
  var values: any = {};
  for (var item in params) {
    values[item] = params[item];
  }
  return values;
}
// eslint-disable-next-line no-unused-vars
export function loop(data: any[], key: any, callback: (arg0: any, arg1: any, arg2: any) => any) {
  data.forEach((item, index, arr) => {
    if (item.key === key) {
      return callback(item, index, arr);
    }
    if (item.children) {
      return loop(item.children, key, callback);
    }
  });
}
export function loopParentKey(data: any[], value: any, keys: any[]) {
  let flag = false;
  data.forEach((item) => {
    let itemFlag = false;
    if (item.title && item.title.indexOf(value) > -1) {
      itemFlag = true;
    }
    if (item.children) {
      const childFlag = loopParentKey(item.children, value, keys);
      if (childFlag) {
        itemFlag = true;
      }
    }
    if (itemFlag) {
      flag = true;
      keys.push(item.key);
    }
  });
  return flag;
}
export function loopLeafKey(data: any[], keys: any[]) {
  // 获取所有选中数据
  data.forEach((item) => {
    if (item.children) {
      return loopLeafKey(item.children, keys);
    } else {
      keys.push(item.key);
    }
  });
}
export function loopKey(data: any[], keys: any[]) {
  // 获取所有选中数据
  data.forEach((item) => {
    keys.push(item.key);
    if (item.children) {
      return loopKey(item.children, keys);
    }
  });
}
export function loopExpandCheck(data: any[], checkedKeys: any[], expandedKeys: any[]) {
  data.forEach((item) => {
    expandedKeys.push(item.key);
    if (item.children) {
      return loopExpandCheck(item.children, checkedKeys, expandedKeys);
    } else {
      checkedKeys.push(item.key);
    }
  });
}
//获取后端返回需要展开的节点
export function loopExpandKeys(data: any[], expandedKeys: any[]) {
  data.forEach((item) => {
    if (item.expanded) {
      expandedKeys.push(item.key);
    }
    if (item.children) {
      return loopExpandKeys(item.children, expandedKeys);
    }
  });
}
/***
 * 时间搓 格式化
 */
export function formatDate(datetime: string | number | Date) {
  const date = new Date(datetime); // 时间戳为10位需*1000，时间戳为13位的话不需乘1000
  const year = date.getFullYear();
  const month = ('0' + (date.getMonth() + 1)).slice(-2);
  const sdate = ('0' + date.getDate()).slice(-2);
  const hour = ('0' + date.getHours()).slice(-2);
  const minute = ('0' + date.getMinutes()).slice(-2);
  const second = ('0' + date.getSeconds()).slice(-2);
  // 拼接
  var result = year + '-' + month + '-' + sdate + ' ' + hour + ':' + minute + ':' + second;
  // 返回
  return result;
}
/**
 * 下划线转驼峰
 * @param string
 * @returns {*}
 */
export function underLine2CamelCase(string: string) {
  return string.replace(/_([a-z])/g, function (all, letter) {
    return letter.toUpperCase();
  });
}

export function isDef(v: null | undefined) {
  return v !== undefined && v !== null;
}
export function isEmptyStr(value: string | null | undefined) {
  let str;
  if (value == null || value == undefined) {
    str = value;
  } else {
    str = value + '';
  }
  if (str == null || str == 'null' || str == undefined || str == 'undefined' || str.match(/^[\s]*$/)) {
    return true;
  } else {
    return false;
  }
}
/**
 * @description   判断数据是否为网址(URL),请传入满足http标准协议的链接
 * @param {String} str_data 待校验的数据
 * @param {Boolean} flag 是否使用严格模式,默认为false
 * @returns {Boolean}, true:是网址
 **/
export function isUrl(str_data: string, flag: boolean) {
  flag = flag || false;
  let regular =
    /^\b(((https?|ftp):\/\/)?[-a-z0-9]+(\.[-a-z0-9]+)*\.(?:com|edu|gov|int|mil|net|org|biz|info|name|museum|asia|coop|aero|[a-z][a-z]|((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]\d)|\d))\b(\/[-a-z0-9_:\@&?=+,.!\/~%\$]*)?)$/i;
  let regular2 = /^((https?|ftp):\/\/)(www\.)?\S{0,30}\.\S+$/i;

  if (regular2.test(str_data) && !flag) {
    return true;
  } else if (regular.test(str_data) && flag) {
    return true;
  } else {
    return false;
  }
}
/***获取url上的参数 */
export function getQueryString(name: string) {
	const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
	const search = window.location.search.split('?')[1] || '';
	if (search) {
		const r:string[] = search.match(reg) || [];
		let s:string = r[2];
		return s;
	} else {
		return '';
	}
}
export function deepClone(obj: any) {
  let newobj: any = Array.isArray(obj) ? [] : {};
  //constructor 属性返回对创建此对象的数组函数的引用。创建相同类型的空数据
  if (typeof obj !== 'object') {
    return;
  } else {
    for (let i in obj) {
      if (typeof obj[i] === 'object' && obj[i]) {
        //判断对象的这条属性是否为对象
        newobj[i] = deepClone(obj[i]); //若是对象进行嵌套调用
      } else {
        newobj[i] = obj[i];
      }
    }
  }
  return newobj; //返回深度克隆后的对象
}
const _toString = Object.prototype.toString;

// 驼峰转换下划线
export function toLine(name: string) {
  return name.replace(/([A-Z])/g, '_$1').toLowerCase();
}
export function isValidKey(key: string | number | symbol, object: object): key is keyof typeof object {
  return key in object;
}
